package org.artifact.core.plugin.netty.server;

import cn.hutool.core.map.MapUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author : SandKing
 * @CreateDate : 2020/3/25 15:42
 * @Description ：Please describe this document
 */
public class NettyUdpServer implements NettyServer{

    private static final Log log = LogFactory.get();


    protected String name;//服务名称

    protected int port;//端口

    protected int heartbeat;//心跳

    protected Bootstrap bootstrap;

    protected EventLoopGroup group;

    @Override
    public void init(Map map) {
        name = MapUtil.getStr(map,"name");
        port = MapUtil.getInt(map,"port");
        heartbeat = MapUtil.getInt(map,"heartbeat");
        bootstrap = new Bootstrap();
        group = new NioEventLoopGroup(1);
        bootstrap.group(group).channel(NioDatagramChannel.class);
        bootstrap.option(ChannelOption.SO_BROADCAST,true);
        bootstrap.option(ChannelOption.SO_RCVBUF,2048*1024);
        bootstrap.option(ChannelOption.SO_SNDBUF,1024*1024);
        //处理业务
        bootstrap.handler(new ChannelInitializer<NioDatagramChannel>() {
            @Override
            protected void initChannel(NioDatagramChannel ch) {
                buildChannelPipeline(ch.pipeline());
            }
        });


    }

    @Override
    public void buildChannelPipeline(ChannelPipeline pipeline) {
    // 配置了心跳功能，则启用心跳机制.
        if (heartbeat > 0) {
            pipeline.addLast("idleStateHandler", new IdleStateHandler(heartbeat, 0, 0, TimeUnit.SECONDS));
        }
    }

    @Override
    public void startup() {
        try {
            bootstrap.bind(port).sync().channel().closeFuture().await();
            log.info("Netty Server udp Start on {}", port);
        }catch (Exception e){
            log.error(e);
        }
    }

    @Override
    public void shutdown() {
        try {
            group.shutdownGracefully().sync();
            log.info("Netty Server udp Stop Success!");
        }catch (Exception e){
            log.error(e);
        }

    }
}
